#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>

// myirq{
//      compatilbe = "hqyj,irq";
//      interrupt-parent = <&gpiof>;
//      interrupts = <9 0>, <7 0>,<8 0>;
// };

struct device_node* node; //获取设备树节点
unsigned int irqno[3] = { 0 }; //解析函数返回值
int ret; //注册中断
char* name[] = { "key1", "key2", "key3" };
irqreturn_t key_irq(int irq, void* dev) //中断处理函数
{
    switch ((int)dev) {
    case 0:
        printk("按键1按下！\n");
        break;
    case 1:
        printk("按键2按下！\n");
        break;
    case 2:
        printk("按键3按下！\n");
        break;
    }

    return IRQ_HANDLED;
}
static int __init mycdev_init(void)
{
    int i = 0;
    // 1.获取设备树节点
    node = of_find_compatible_node(NULL, NULL, "hqyj,irq");
    if (node == NULL) {
        printk("获取设备树节点失败\n");
        return -ENODATA;
    }
    // 2.解析得到软中断号
    for (i = 0; i < ARRAY_SIZE(irqno); i++) {
        irqno[i] = irq_of_parse_and_map(node, i);
        if (irqno[i] == 0) {
            printk("解析失败\n");
            return -EAGAIN;
        }
        // 3.注册中断
        ret = request_irq(irqno[i], key_irq, IRQF_TRIGGER_FALLING, name[i], (void*)i);
        if (ret) {
            printk("注册中断失败\n");
            return ret;
        }
    }

    return 0;
}

static void __exit mycdev_exit(void)
{
    int i = 0;
    for (i = 0; i < ARRAY_SIZE(irqno); i++) {
        free_irq(irqno[i], (void*)i);
    }
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");